package GUI;

import java.awt.Dimension;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import javax.swing.tree.*;

import sql.IndexItem;
import ExecuteEngine.*;
import Socket.Abort_Message;

public class TreePanel extends JPanel {

	private static final long serialVersionUID = 6172624208775216641L;
	
	private ClientFrame frame;
	private JTree tree;
	DefaultMutableTreeNode nodeTable;
	DefaultMutableTreeNode nodeView;
	DefaultMutableTreeNode nodeIndex;
	
	public TreePanel(ClientFrame f) {
		frame = f;
		setBorder(BorderFactory.createTitledBorder(frame.username+"'s database"));
		
		initComponent();
		
		tree.addMouseListener(new MouseListener() {
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount()!=2)
					return;
				TreePath tp=tree.getSelectionPath();
				if (tp != null) {
					Object[] o = tp.getPath();
					Object selected = o[o.length-1];
					if (selected instanceof DefaultMutableTreeNode && ((DefaultMutableTreeNode)selected).getLevel()==2) {
						DefaultMutableTreeNode leaf = (DefaultMutableTreeNode)selected;
						if (leaf.getParent().toString()=="Index")
							return;
						try {
							frame.client.queryExec("select * from "+leaf.toString());
							frame.message.AddMessage("Success: Query Table Success!");
						} catch (Abort_Message m) {
							frame.message.AddMessage("Warning: " + m.getMessage());
						}
						frame.table.updateTable();
					}
				}
			}
			public void mouseEntered(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
			public void mousePressed(MouseEvent e) {}
			public void mouseReleased(MouseEvent e) {}
		});

	}
	
	private void initComponent() {
		DefaultMutableTreeNode  root = new DefaultMutableTreeNode (frame.username);
		nodeTable = new DefaultMutableTreeNode("Table");
		nodeView = new DefaultMutableTreeNode("View");
		nodeIndex = new DefaultMutableTreeNode("Index");
		root.add(nodeTable);
		root.add(nodeView);
		root.add(nodeIndex);
		root.toString();
		
		tree = new JTree(root);
		add(tree);
		tree.setBounds(5, 5, 190, 420);
		tree.setPreferredSize(new Dimension(185, 390));
		tree.setOpaque(false);
		initTree();
	}

	public void initTree() {
		List<String> tableList = frame.client.getTables();
		List<IndexItem> indexList = frame.client.getIndexes();
//		List<String> viewList = frame.client.getViews();
		List<String> titleList;
		if (tableList != null)
			for (String tname : tableList)  {
				DefaultMutableTreeNode t = new DefaultMutableTreeNode(tname);
				nodeTable.add(t);
				titleList = frame.client.getTitles(tname);
				if (titleList!=null) {
					for (String ttn : titleList)
						t.add(new DefaultMutableTreeNode(ttn));
				}
			}
//		nodeTable.add(new DefaultMutableTreeNode("test"));
//		if (viewList!=null)
//			for (String vname : viewList)
//				nodeView.add(new DefaultMutableTreeNode(vname));
		if (indexList!=null)
			for (IndexItem iname : indexList)
				nodeIndex.add(new DefaultMutableTreeNode(iname));		
	}
	
	@SuppressWarnings("unchecked")
	public void updateTree() {
		int op = frame.client.getOp();
		if (op<0)
			return;
		String rel = frame.client.getRel();
		IndexItem index = frame.client.getIndexItem();
		String view = frame.client.getView();
		if (rel != null) { //update table
			if (op == Special_op.PLUS) { // add a table
				DefaultMutableTreeNode newnode = new DefaultMutableTreeNode(rel);
				List<String> titles = frame.client.getTitles(rel);
				for (int i=0; i<titles.size(); ++i)
					newnode.add(new DefaultMutableTreeNode(titles.get(i)));
				nodeTable.add(newnode);
				tree.updateUI();
			} else { // remove a table
				for (Enumeration e =  nodeTable.children(); e.hasMoreElements(); ) {
					DefaultMutableTreeNode n = (DefaultMutableTreeNode)e.nextElement();
					if (n.toString().compareTo(rel)==0) {
						nodeTable.remove(n);
						tree.updateUI();
						return;
					}
				}
				throw new RuntimeException();
			}
		} else if (index != null) { //update index
			if (op == Special_op.PLUS) {
				nodeIndex.add(new DefaultMutableTreeNode(index.tableName + "." + index.attrName));
				tree.updateUI();
			} else {
				for (Enumeration e = nodeIndex.children(); e.hasMoreElements(); ) {
					DefaultMutableTreeNode n = (DefaultMutableTreeNode)e.nextElement();
					if (n.toString().compareTo(rel)==0) {
						nodeIndex.remove(n);
						tree.updateUI();
						return;
					}
				}
				throw new RuntimeException();
			}
		} else if (view != null) { //update view
			if (op == Special_op.PLUS) { // add a table
				DefaultMutableTreeNode newnode = new DefaultMutableTreeNode(view);
				nodeView.add(newnode);
				tree.updateUI();
			} else { // remove a table
				for (Enumeration e =  nodeView.children(); e.hasMoreElements(); ) {
					DefaultMutableTreeNode n = (DefaultMutableTreeNode)e.nextElement();
					if (n.toString().compareTo(rel)==0) {
						nodeView.remove(n);
						tree.updateUI();
						return;
					}
				}
				throw new RuntimeException();
			}
		}
	}

}
